package cn.virens.config;

import cn.virens.common.mybatis.mapper.mybatis.MybatisModelOperTimeInterceptor;
import cn.virens.common.util.exception.APIException;
import cn.virens.util.ResourceUtil;
import com.alibaba.druid.pool.DruidDataSource;
import com.github.pagehelper.PageInterceptor;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.context.annotation.PropertySource;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import java.io.IOException;
import java.sql.SQLException;
import java.util.Properties;

@Configuration
@PropertySource("classpath:/spring-autoconfig.properties")
public class PropertiesConfig extends AbstractSpringConfig {
    protected final Logger logger = LoggerFactory.getLogger(getClass());

    /**
     * MyBatis 数据连接地址池配置
     *
     * @throws IOException
     * @throws SQLException
     */
    @Bean(name = "druidDataSource", initMethod = "init", destroyMethod = "close")
    public DruidDataSource druidDataSource() throws SQLException {
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName(property("jdbc.driverClass"));
        dataSource.setUsername(property("jdbc.username"));
        dataSource.setPassword(property("jdbc.password"));
        dataSource.setUrl(property("jdbc.url"));
        // 拦截配置
        dataSource.setFilters("stat,wall,slf4j");

        dataSource.setAsyncInit(true);
        // 配置初始化大小、最小、最大
        dataSource.setInitialSize(1);
        dataSource.setMaxActive(20);
        dataSource.setMaxWait(6000);

        return dataSource;
    }

    /**
     * mysql事务管理
     */
    @Bean(name = "txManager")
    @DependsOn(value = "druidDataSource")
    public DataSourceTransactionManager dataSourceTransactionManager() throws SQLException {
        return new DataSourceTransactionManager(druidDataSource());
    }

    @Bean("sqlSessionFactoryBuilder")
    public SqlSessionFactoryBuilder sqlSessionFactoryBuilder() throws APIException {
        return new SqlSessionFactoryBuilder();
    }

    /**
     * MyBatis配置 :配置sqlSessionFactory
     *
     * @param sqlSessionFactoryBuilder
     * @return
     * @throws APIException
     * @throws IOException
     * @throws SQLException
     */
    @Bean("sqlSessionFactoryBean")
    @DependsOn(value = {"druidDataSource", "sqlSessionFactoryBuilder"})
    public SqlSessionFactoryBean sqlSessionFactoryBean() throws APIException, IOException, SQLException {
        MybatisModelOperTimeInterceptor interceptor0 = new MybatisModelOperTimeInterceptor();

        // 分页拦截器
        PageInterceptor interceptor1 = new PageInterceptor();
        Properties properties = new Properties();
        properties.put("helperDialect", "mysql");

        interceptor1.setProperties(properties);

        // 创建SqlSession工厂
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        sqlSessionFactoryBean.setMapperLocations(ResourceUtil.getResources("classpath:mysql/**/*.xml"));
        sqlSessionFactoryBean.setSqlSessionFactoryBuilder(sqlSessionFactoryBuilder());
        sqlSessionFactoryBean.setPlugins(interceptor0, interceptor1);
        sqlSessionFactoryBean.setDataSource(druidDataSource());

        return sqlSessionFactoryBean;
    }

    @Bean
    @DependsOn("sqlSessionFactoryBean")
    public static MapperScannerConfigurer mapperScannerConfigurer() throws APIException {
        MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
        mapperScannerConfigurer.setSqlSessionFactoryBeanName("sqlSessionFactoryBean");
        mapperScannerConfigurer.setBasePackage("cn.virens.mybaits.mapper");

        return mapperScannerConfigurer;
    }
}